package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 菜品管理
 */
@Slf4j
@RestController
@RequestMapping("/dish")

public class DishController {
    @Autowired
    private DishFlavorService dishFlavorService;
    @Autowired
    private DishService dishService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private SetmealService setmealService;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 新增菜品
     * @param dishDto
     * @return
     */
    @PostMapping
    @CacheEvict(value = "dishCache",allEntries = true)
    public R<String> save(@RequestBody DishDto dishDto){
        //DishDto包含Dish类和DishFlavor类的属性
        dishService.saveWithFlavor(dishDto);

        //数据库分类下的菜品修改，缓存删除
        /*
        String key="dish_"+dishDto.getCategoryId()+"_"+dishDto.getStatus();
        redisTemplate.delete(key);

         */

        return R.success("菜品新增成功");
    }
    /**
     * 菜品信息分页查询
     *
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name){

        Page<Dish> pageInfo=new Page<>(page,pageSize);
        Page<DishDto> pageInfoDto=new Page<>(page,pageSize);

        LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(name!=null,Dish::getName,name);
        lambdaQueryWrapper.orderByDesc(Dish::getUpdateTime);
        dishService.page(pageInfo,lambdaQueryWrapper);

        //复制Dish到DishDto，Dish中不包含菜品分类名称，需要使用DishDto加上去
        BeanUtils.copyProperties(pageInfo,pageInfoDto,"records");

        List<Dish> records=pageInfo.getRecords();

        List<DishDto> list= records.stream().map((item)->{
            DishDto dishDto=new DishDto();
            //拷贝普通属性
            BeanUtils.copyProperties(item,dishDto);
            //查询分类名称，复制到dishDto
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if(category!=null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return  dishDto;
        }).collect(Collectors.toList());

        pageInfoDto.setRecords(list);
        return R.success(pageInfoDto);
    }
    /**
     *  根据id查询菜品信息和对应的口味信息
     */
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品dish信息及dish_flavor口味信息
     * @param dishDto
     * @return
     */
    @PutMapping
    @CacheEvict(value = "dishCache",allEntries = true)
    public R<String> update(@RequestBody DishDto dishDto){

        dishService.updateWithFlavor(dishDto);
        //数据库分类下的菜品修改，缓存删除
        /*
        String key="dish_"+dishDto.getCategoryId()+"_"+dishDto.getStatus();
        redisTemplate.delete(key);

         */

        return R.success("菜品修改成功");
    }

    /**
     * 删除该id的dish表和dish_flavor表
     * @param ids
     * @return
     */
    @DeleteMapping
    @CacheEvict(value = "dishCache",allEntries = true)
    public R<String> delete(Long[] ids){
        for (Long id:ids) {

            //查询是否可以删除，如果起售或者在套餐中就无法删除
            LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.eq(SetmealDish::getDishId,id);
            int count=setmealDishService.count(queryWrapper);
            if(count>0){
                //如果不能删除，抛出一个异常
                throw new CustomException("该菜品在套餐中，不能删除!");
            }
            Dish dish = dishService.getById(id);
            if(dish!=null&&dish.getStatus()==1){
                throw new CustomException("该菜品在起售中，不能删除!");
            }
            /*
            //数据库分类下的菜品修改，缓存删除
            String key="dish_"+dish.getCategoryId()+"_"+dish.getStatus();
            redisTemplate.delete(key);
             */
            //删除
            dishService.removeById(id);
            dishFlavorService.removeById(id);
        }
        return R.success("菜品删除成功");
    }
    /**
     * 停售和起售某id的菜品
     */
    @PostMapping("/status/0")
    @CacheEvict(value = "dishCache",allEntries = true)
    public R<String> Status(Long[] ids){
        for (Long id:ids
        ) {
            //查询是否可以停售，如果在起售的套餐中不能停售
            LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.eq(SetmealDish::getDishId,id);
            List<SetmealDish> list = setmealDishService.list(queryWrapper);
            for (SetmealDish setmealDish: list) {
                Long setmealId = setmealDish.getSetmealId();
                Setmeal setmeal = setmealService.getById(setmealId);
                if(setmeal==null||setmeal.getStatus()==1){
                    throw new CustomException("该菜品在起售的套餐中!不能停售!");
                }
            }
            //停售
            Dish dish = dishService.getById(id);
            dish.setStatus(0);
            dishService.updateById(dish);

        }
        return R.success("停售成功");
    }
    @PostMapping("/status/1")
    @CacheEvict(value = "dishCache",allEntries = true)
    public R<String> Status1(Long[] ids){
        for (Long id:ids
        ) {
            Dish dish = dishService.getById(id);
            dish.setStatus(1);
            dishService.updateById(dish);

        }
        return R.success("起售成功");
    }

    /**
     * 根据条件来查询对应的菜品的数据，如菜品的分类：categoryId指川菜
     * @param dish
     * @return
     */
    @GetMapping("/list")
    @Cacheable(value = "dishCache",key="#dish.CategoryId+'_'+#dish.Status")
    public R<List<DishDto>> list(Dish dish){
        //先从redis获取缓存数据，按照分类查询：川菜，儿童套餐等...
        /*
        String key="dish_"+dish.getCategoryId()+"_"+dish.getStatus();
        List<DishDto> dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);
        if(dishDtoList!=null){
            return R.success(dishDtoList);
        }
         */
        //redis不存在，在查询数据库
        //构造查询条件
        LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
        //设置条件，等值查询，排序
        queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId()); //分类的id相同，都是川菜、儿童套餐等
        queryWrapper.eq(Dish::getStatus,1); //在售的菜品
        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(queryWrapper);


        //复制Dish到DishDto，Dish中不包含菜品口味，需要使用DishDto加上去
        List<DishDto> listDto= list.stream().map((item)->{
            DishDto dishDto=new DishDto();
            //拷贝普通属性
            BeanUtils.copyProperties(item,dishDto);
            //查询分类名称，复制到dishDto
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if(category!=null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            //通过dishId找到口味表中的口味信息
            Long dishId=item.getId();
            LambdaQueryWrapper<DishFlavor> queryWrapper1=new LambdaQueryWrapper<>();
            queryWrapper1.eq(DishFlavor::getDishId,dishId);
            List<DishFlavor> list1 = dishFlavorService.list(queryWrapper1);
            dishDto.setFlavors(list1);
            return  dishDto;
        }).collect(Collectors.toList());
        /*
        //数据库中该菜品分类下的数据放入redis
        redisTemplate.opsForValue().set(key,listDto,30, TimeUnit.MINUTES);
         */
        return R.success(listDto);
    }
}
